use serde::{de::DeserializeOwned, Serialize};
use std::{
    fs::File,
    io::{Seek, SeekFrom},
};

pub fn store<T: Serialize>(mut f: &File, t: &T) -> std::io::Result<()> {
    f.set_len(0)?;
    f.seek(SeekFrom::Start(0))?;
    serde_json::to_writer(f, t)?;
    Ok(())
}

pub fn load_or_write_default<T: Default + Serialize + DeserializeOwned>(
    mut f: &File,
) -> std::io::Result<T> {
    match serde_json::from_reader::<_, T>(f) {
        Ok(s) => Ok(s),
        Err(e) if e.is_io() => Err(e.into()),
        Err(_) => {
            let t = T::default();
            f.set_len(0)?;
            f.seek(SeekFrom::Start(0))?;
            serde_json::to_writer(f, &t)?;
            Ok(t)
        }
    }
}

pub fn system_shutdown_now() {
    if cfg!(target_os = "windows") {
        let _ = std::process::Command::new("cmd")
            .args(["/C", "psshutdown -f -s -t 0"])
            .output();
    } else {
        let _ = std::process::Command::new("sh")
            .args(["-c", "shutdown now"])
            .output();
    }
}

pub fn system_suspend() {
    if cfg!(target_os = "windows") {
        let _ = std::process::Command::new("cmd")
            .args(["/C", "psshutdown -h -t 0"])
            .output();
    } else {
        let _ = std::process::Command::new("sh")
            .args(["-c", "systemctl suspend"])
            .output();
    }
}

pub fn system_shutdown(countdown_mins: usize) {
    if cfg!(target_os = "windows") {
        let _ = std::process::Command::new("cmd")
            .args([
                "/C".to_owned(),
                format!("psshutdown -s -t {}", countdown_mins * 60),
            ])
            .output();
    } else {
        let _ = std::process::Command::new("sh")
            .args(["-c".to_owned(), format!("shutdown +{countdown_mins}")])
            .output();
    }
}
